package com.liwenfeng.diancanspringboot.service.impl;

import com.liwenfeng.diancanspringboot.common.exception.OrderBusinessException;
import com.liwenfeng.diancanspringboot.mapper.*;
import com.liwenfeng.diancanspringboot.pojo.dto.StatementSubmitDTO;
import com.liwenfeng.diancanspringboot.pojo.entity.OrderDetail;
import com.liwenfeng.diancanspringboot.pojo.entity.Orders;
import com.liwenfeng.diancanspringboot.pojo.entity.Statement;
import com.liwenfeng.diancanspringboot.pojo.entity.Turnover;
import com.liwenfeng.diancanspringboot.pojo.vo.StatementVO;
import com.liwenfeng.diancanspringboot.service.StatementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Slf4j
public class StatementServiceImpl implements StatementService {
    @Autowired
    private StatementMapper statementMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private TurnoverMapper turnoverMapper;

    // 结账，生成结账单(浏览器端)
    @Transactional
    @Override
    public void submit(StatementSubmitDTO statementSubmitDTO) {
        List<Orders> unpayByTurnoverId = orderMapper.getUnpayByTurnoverId(statementSubmitDTO.getTurnoverId());
        if (statementSubmitDTO.getOrderIds().size() != unpayByTurnoverId.size() || !new HashSet<>(statementSubmitDTO.getOrderIds()).containsAll(unpayByTurnoverId.stream().map(Orders::getId).toList())) {
            throw new OrderBusinessException("数据发生了变化，请刷新后重试");
        }
        Statement statement = new Statement();
        BeanUtils.copyProperties(statementSubmitDTO, statement);
        statementMapper.insert(statement);
        for (Long orderId : statementSubmitDTO.getOrderIds()) {
            Orders orders = new Orders();
            orders.setId(orderId);
            orders.setStatementId(statement.getId());
            orderMapper.update(orders);
        }
        Turnover turnover = new Turnover();
        turnover.setId(statement.getTurnoverId());
        turnover.setStatus(Turnover.STATUS_PARTIAL);
        turnoverMapper.update(turnover);
    }

    // 获取结算单详情
    @Override
    public List<OrderDetail> getOrderDetailByStatementId(Long statementId) {
        List<Long> orderIdList = orderMapper.getOrderListByStatementId(statementId);
        ArrayList<OrderDetail> orderDetailList = new ArrayList<>();
        if (orderIdList != null) {
            for (Long orderId : orderIdList) {
                List<OrderDetail> orderDetails = orderDetailMapper.getValidByOrderId(orderId);
                orderDetailList.addAll(orderDetails);
            }
        }
        return mergeOrderDetails(orderDetailList);
    }

    @Override
    public void update(Statement statement) {
        statementMapper.update(statement);
    }

    @Override
    public List<StatementVO> list(Long turnoverId) {
        List<Statement> statements = statementMapper.getByTurnoverId(turnoverId);
        if (statements == null || statements.size() == 0) {
            throw new OrderBusinessException("当前流水单没有结账单");
        }
        return statements.stream().map(item -> {
            StatementVO statementVO = new StatementVO();
            BeanUtils.copyProperties(item, statementVO);
            statementVO.setOrderDetails(getOrderDetailByStatementId(item.getId()));
            return statementVO;
        }).toList();
    }

    // 按名称，口味，价格合并订单详情的数量
    private List<OrderDetail> mergeOrderDetails(List<OrderDetail> orderDetails) {
        // 使用 Map 来存储合并后的结果，key 是 name + dishFlavor 的组合
        Map<String, OrderDetail> map = new HashMap<>();

        for (OrderDetail detail : orderDetails) {
            // 生成唯一的 key
            String key = detail.getName() + "|" + detail.getDishFlavor() + "|" + detail.getAmount();

            // 如果 Map 中已经存在相同的 key，累加 number
            if (map.containsKey(key)) {
                OrderDetail existingDetail = map.get(key);
                existingDetail.setNumber(existingDetail.getNumber() + detail.getNumber());
            } else {
                // 如果不存在，直接放入 Map
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(detail, orderDetail);
                map.put(key, orderDetail);
            }
        }

        // 将 Map 中的值转换为 List
        return new ArrayList<>(map.values());
    }
}
